package test

import (
	"common_demo/internal/config"
	chatgpt_api "common_demo/pkg/ai/chatgpt"
	deepseek_api "common_demo/pkg/ai/deepseek"
	"common_demo/pkg/logger"
	"common_demo/pkg/logger/sink"
	"context"
	"fmt"
	"testing"
	"time"

	"github.com/go-deepseek/deepseek"
	"github.com/go-deepseek/deepseek/request"
	"github.com/gorilla/websocket"
	"github.com/openai/openai-go"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func Test(t *testing.T) {
}

func TestLoggerWsSink(t *testing.T) {
	sinkUrl := sink.SCHEMA_WS + "://0.0.0.0:8080/ws"

	if err := zap.RegisterSink(
		sink.SCHEMA_WS,
		logger.NewCacheSink(sink.SCHEMA_WS, sink.NewWsSink),
	); err != nil {
		fmt.Println("failed to register sink, error:", err.Error())
		t.FailNow()
	}

	wsSinklog, err := logger.NewLogger(
		&config.LoggerConfig{
			Level: "DEBUG",
			OutputPaths: []string{
				"/var/log/testdemo.log",
				sinkUrl,
			},
			ErrorOutputPaths: []string{
				"/var/log/testdemo_error.log",
				sinkUrl,
			},
		},
	)
	if err != nil {
		fmt.Println("failed to new logger, error:", err.Error())
		t.FailNow()
	}
	defer logger.CloseSink(sinkUrl)
	defer wsSinklog.Sync()

	test := 0
	for {
		wsSinklog.Infof("testing...%d", test)
		test++
		if test > 3 {
			break
		}
		time.Sleep(time.Second)
	}
}

func TestLoggerInterceptor(t *testing.T) {
	var testIndex int

	logger, err := logger.NewLogger(
		&config.LoggerConfig{
			Level:       "DEBUG",
			OutputPaths: []string{"/var/log/testdemo.log"},
		},
		logger.WithInterceptor(
			func(entry zapcore.Entry) error {
				testIndex++
				return nil
			},
		),
	)
	if err != nil {
		t.FailNow()
	}
	defer logger.Sync()

	go func() {
		for {
			fmt.Println("testIndex:", testIndex)
			time.Sleep(3 * time.Second)
		}
	}()

	for {
		logger.Infof("testing...%d", testIndex)
		time.Sleep(time.Second)
		if testIndex > 3 {
			return
		}
	}
}

func TestChatgpt(t *testing.T) {
	cli := chatgpt_api.NewClient()
	result, err := chatgpt_api.SendMessage(context.Background(), cli, openai.ChatCompletionNewParams{
		Messages: []openai.ChatCompletionMessageParamUnion{
			openai.UserMessage("Hello"),
		},
		Model: openai.ChatModelGPT4o,
	})
	if err != nil {
		fmt.Println("ERROR:", err.Error())
		t.FailNow()
	}
	fmt.Println("Result:", result)
}

func TestDeepseek(t *testing.T) {
	cli, err := deepseek_api.NewClient()
	if err != nil {
		fmt.Println("ERROR:", err.Error())
		t.FailNow()
	}
	result, err := deepseek_api.SendMessage(context.Background(), cli, &request.ChatCompletionsRequest{
		Model:  deepseek.DEEPSEEK_CHAT_MODEL,
		Stream: false,
		Messages: []*request.Message{
			{
				Role:    "user",
				Content: "Hello Deepseek!", // set your input message
			},
		},
	})
	if err != nil {
		fmt.Println("ERROR:", err.Error())
		t.FailNow()
	}
	fmt.Println("Result:", result)
}

func TestWebsocket(t *testing.T) {
	url := "ws://localhost:8080/ws"
	conn, _, err := websocket.DefaultDialer.Dial(url, nil)
	if err != nil {
		fmt.Println("failed to connect server, error:", err.Error())
		return
	}
	defer conn.Close()

	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(10*time.Second))
	defer cancel()

	fmt.Println("connected to server...")

	go func() {
		for {
			select {
			case <-ctx.Done():
				return
			default:
				_, msg, err := conn.ReadMessage()
				if err != nil {
					fmt.Println("failed to receive message, error:", err.Error())
					return
				}
				fmt.Println("received message:", string(msg))
			}
		}
	}()

	for {
		select {
		case <-ctx.Done():
			fmt.Println("is time to close...")
			if err := conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")); err != nil {
				fmt.Println("failed to send closed message, error:", err.Error())
			}
			return
		case <-time.After(time.Second):
			msg := []byte("client time: " + time.Now().Format("2006-01-02 15:04:05"))
			if err := conn.WriteMessage(websocket.TextMessage, msg); err != nil {
				fmt.Println("failed to send message, error:", err.Error())
				return
			}
		}
	}
}
